﻿using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using OfficeOpenXml;
using System.Text;

namespace QDWK.Class
{
    public class CQdwk
    {
        public string Session { get; set; }
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly SysInfo _sysInfo;
        private readonly ILogger<CQdwk> _logger;
        private string VendorCode { get; set; }

        public List<VendorStock> VendorStocks = new List<VendorStock>();
        public CQdwk(SysInfo sysInfo, IHttpClientFactory httpClientFactory,ILogger<CQdwk> logger)
        {
            _sysInfo = sysInfo;
            _httpClientFactory = httpClientFactory;
            _logger = logger;
            _logger.LogInformation($"{nameof(CQdwk)}");
            VendorCode = "87100012";
        }

        public async Task<bool> GetSession()
        {          
            var cmdInfo = new
            {
                session = "******",
                datas = new List<data>
                {
                    new data { id = "user", val = $"txt:{_sysInfo.UserName}"},
                    new data { id = "password", val = $"txt:{_sysInfo.Password}"},
                    new data { id = "serialnum", val = $"txt:{_sysInfo.SerialNum}" }                                        
                }
            };
            string json = JsonConvert.SerializeObject(cmdInfo);
            json = JsonHelper.RemoveQuotesFromKeys(json);
            var content = new StringContent(json, Encoding.UTF8, "application/zsml");

            try
            {
                var client = _httpClientFactory.CreateClient();
                var response = await client.PostAsync(_sysInfo.LoginUrl, content);
                response.EnsureSuccessStatusCode();

                string result = await response.Content.ReadAsStringAsync();

                var doc = JsonConvert.DeserializeObject<document>(result);
                if (doc?.header != null && doc.body?.action == "sys")
                {
                    Session = doc.header.session;
                    return true;
                }
                return false;
            }
            catch (HttpRequestException httpEx)
            {
                Console.WriteLine($"HTTP 请求失败: {httpEx.Message}");
                _logger.LogError($"HTTP 请求失败: {httpEx.Message}");
                return false;
            }
            catch (JsonException jsonEx)
            {
                Console.WriteLine($"JSON 反序列化失败: {jsonEx.Message}");
                _logger.LogError($"JSON 反序列化失败: {jsonEx.Message}");
                return false;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"未知错误: {ex.Message}");
                _logger.LogError($"未知错误: {ex.Message}");
                return false;
            }
        }

        public async Task<VendorStock> GetData(string key)
        {
            var cmdInfo = new CmdInfo()
            {
                session = Session,
                cmdkey = "refresh",
                datas = new List<data>
                {
                    new data { id = "dataType", val = ""},
                    new data { id = "ord", val = ""},
                    new data { id = "searchKey", val = $"{key}" },
                    new data { id = "pagesize", val = "10" },
                    new data { id = "pageindex", val = "1" },
                    new data { id = "_rpt_sort", val = "_rpt_sort" },
                }
            };
            string json = JsonConvert.SerializeObject(cmdInfo);
            json = JsonHelper.RemoveQuotesFromKeys(json);          

            var content = new StringContent(json, Encoding.UTF8, "application/zsml");

            try
            {
                var client = _httpClientFactory.CreateClient();
                var response = await client.PostAsync(_sysInfo.QueryUrl, content);
                response.EnsureSuccessStatusCode();

                string result = await response.Content.ReadAsStringAsync();

                var doc = JsonConvert.DeserializeObject<document>(result);
                if (doc?.header != null && doc?.header.message == "ok" 
                    && doc?.body?.action == "table"
                    && doc?.body?.source != null && doc?.body?.source?.table != null
                    && doc?.body?.source?.table?.rows != null 
                    && doc?.body?.source?.table?.rows.Count > 0)
                {
                    var vendorStock = new VendorStock()
                    {
                        vendorCode = VendorCode,
                        materialCode = doc?.body?.source?.table?.rows[0][3].ToString(),
                        stock = doc?.body?.source?.table?.rows[0][2].ToString(),
                        stock_date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        unit = doc?.body?.source?.table?.rows[0][5].ToString()
                    };
                    VendorStocks.Add(vendorStock);

                    return vendorStock;
                }

                _logger.LogError($"Key:{key} 数据不正确: {result}");
            }
            catch (HttpRequestException httpEx)
            {
                Console.WriteLine($"HTTP 请求失败: {httpEx.Message}");
                _logger.LogError($"HTTP 请求失败: {httpEx.Message}");
            }
            catch (JsonException jsonEx)
            {
                Console.WriteLine($"JSON 反序列化失败: {jsonEx.Message}");
                _logger.LogError($"JSON 反序列化失败: {jsonEx.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"未知错误: {ex.Message}");
                _logger.LogError($"未知错误: {ex.Message}");                
            }

            return null;
        }

        public List<MesData> ReadExcel(string filePath)
        {
            ExcelPackage.License.SetNonCommercialOrganization("My Noncommercial organization");
            using (var package = new ExcelPackage(new FileInfo("mesdata.xlsx")))
            {
                // 获取第一个工作表
                ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
                //直接通过列索引获取数据
                var lstMesData = new List<MesData>();

                var stock_date = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}";
                // 遍历数据行（从第2行开始）
                for (int row = 2; row <= worksheet.Dimension.End.Row; row++)
                {
                    var item = new MesData()
                    {
                        RowId = row,
                        vendorCode = VendorCode,
                        materialCode = worksheet.Cells[row, 1].Value?.ToString(),
                        VendorMaterialCode = worksheet.Cells[row, 15].Value?.ToString(),
                        materialName = worksheet.Cells[row, 16].Value?.ToString(),
                        deliveryPeriod = worksheet.Cells[row, 18].Value?.ToString(),
                        stock_date = stock_date,
                        unit = "",
                        remark1 = worksheet.Cells[row, 20].Value?.ToString(),
                        remark2 = worksheet.Cells[row, 21].Value?.ToString(),
                        remark4 = worksheet.Cells[row, 19].Value?.ToString()                        
                    };
                    lstMesData.Add(item);
                }

                return lstMesData;
            }
        }

        public async Task<bool> WriteExcel(List<MesData> mesData)
        {
            if (mesData == null || mesData.Count == 0)
                return false;

            ExcelPackage.License.SetNonCommercialOrganization("My Noncommercial organization");
            using (var package = new ExcelPackage(new FileInfo("mesdata.xlsx")))
            {
                // 获取第一个工作表
                ExcelWorksheet worksheet = package.Workbook.Worksheets[0];

                foreach (var item in mesData)
                {
                    //修改单元格的值
                    worksheet.Cells[item.RowId, 17].Value = item.stock;
                }

                //保存到新文件（保留所有格式）
                package.SaveAsAsync(new FileInfo($"{AppContext.BaseDirectory}MesHistoryData/{DateTime.Now:yyyyMMddHHmmss}.xls"));
                return true;
            }

            return false;
        }
    }
}
